﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace CSharpWrapper
{
    internal class ConfPlaybackWrapper : IConferencePlayback
    {
        public delegate void OnAddSessionDelegate(uint rec_session, int rec_type,
            String account, String name);
        public delegate void OnRemoveSessionDelegate(uint rec_session, int rec_type);
        public delegate void OnSessionVideoResolutionChangedDelegate(uint rec_session,
            int old_width, int old_height, int new_width, int new_height);
        public delegate void OnPlaybackOpenDelegate(int error);
        public delegate void OnPlaybackPlayDelegate(int error);
        public delegate void OnPlaybackPauseDelegate(int error);
        public delegate void OnPlaybackContinueDelegate(int error);
        public delegate void OnPlaybackCompleteDelegate();

        [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
        public struct ConfPlaybackCallback
        {
            public OnAddSessionDelegate OnAddSessionDelegate_;
            public OnRemoveSessionDelegate OnRemoveSessionDelegate_;
            public OnSessionVideoResolutionChangedDelegate OnSessionVideoResolutionChangedDelegate_;
            public OnPlaybackOpenDelegate OnPlaybackOpenDelegate_;
            public OnPlaybackPlayDelegate OnPlaybackPlayDelegate_;
            public OnPlaybackPauseDelegate OnPlaybackPauseDelegate_;
            public OnPlaybackContinueDelegate OnPlaybackContinueDelegate_;
            public OnPlaybackCompleteDelegate OnPlaybackCompleteDelegate_;
        }

        public void OnAddSession(uint rec_session, int rec_type,
            String account, String name)
        {
            foreach (IConferencePlaybackObserver observer in observer_list_)
                observer.OnAddSession(rec_session, (LMRecSessionType)rec_type, account, name);
        }

        public void OnRemoveSession(uint rec_session, int rec_type)
        {
            foreach (IConferencePlaybackObserver observer in observer_list_)
                observer.OnRemoveSession(rec_session, (LMRecSessionType)rec_type);
        }

        public void OnSessionVideoResolutionChanged(uint rec_session,
            int old_width, int old_height, int new_width, int new_height)
        {
            foreach (IConferencePlaybackObserver observer in observer_list_)
                observer.OnSessionVideoResolutionChanged(rec_session, old_width, old_height, new_width, new_height);
        }

        public void OnPlaybackOpen(int error)
        {
            foreach (IConferencePlaybackObserver observer in observer_list_)
                observer.OnPlaybackOpen(error);
        }

        public void OnPlaybackPlay(int error)
        {
            foreach (IConferencePlaybackObserver observer in observer_list_)
                observer.OnPlaybackPlay(error);
        }

        public void OnPlaybackPause(int error)
        {
            foreach (IConferencePlaybackObserver observer in observer_list_)
                observer.OnPlaybackPause(error);
        }

        public void OnPlaybackContinue(int error)
        {
            foreach (IConferencePlaybackObserver observer in observer_list_)
                observer.OnPlaybackContinue(error);
        }

        public void OnPlaybackComplete()
        {
            foreach (IConferencePlaybackObserver observer in observer_list_)
                observer.OnPlaybackComplete();
        }

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_playback_set_callback")]
        private static extern void lm_conf_playback_set_callback(
	        IntPtr instance,
	        ref ConfPlaybackCallback callback);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_playback_StartPlayback")]
        private static extern int lm_conf_playback_StartPlayback(
	        IntPtr instance,
	        String file_name);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_playback_PlayPlayback")]
        private static extern int lm_conf_playback_PlayPlayback(IntPtr instance, ref String play_accounts, int count);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_playback_PausePlayback")]
        private static extern int lm_conf_playback_PausePlayback(IntPtr instance);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_playback_ContinuePlayback")]
        private static extern int lm_conf_playback_ContinuePlayback(IntPtr instance);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_playback_StopPlayback")]
        private static extern int lm_conf_playback_StopPlayback(IntPtr instance);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_playback_StartRepair")]
        private static extern int lm_conf_playback_StartRepair(IntPtr instance, String file_name);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_playback_StopRepair")]
        private static extern int lm_conf_playback_StopRepair(IntPtr instance);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_playback_AddPreview")]
        private static extern int lm_conf_playback_AddPreview(
	        IntPtr instance,
	        int rec_session,
	        IntPtr windows,
	        ref int id_preview,
	        int z_order,
	        float left,
	        float top,
	        float right,
	        float bottom);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_playback_RemovePreview")]
        private static extern int lm_conf_playback_RemovePreview(
	        IntPtr instance, 
	        int rec_session, 
	        int id_preview);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_playback_GetRenderSnapshot")]
        private static extern int lm_conf_playback_GetRenderSnapshot(
	        IntPtr instance,
	        int rec_session,
	        int id_preview, 
	        String file_name);


        private IntPtr c_instance_;
        private List<IConferencePlaybackObserver> observer_list_;
        private ConfPlaybackCallback conf_playback_callback_;

        public ConfPlaybackWrapper(IntPtr c_instance)
        {
            c_instance_ = c_instance;
            observer_list_ = new List<IConferencePlaybackObserver>();
            conf_playback_callback_ = new ConfPlaybackCallback();
            conf_playback_callback_.OnAddSessionDelegate_ = new OnAddSessionDelegate(OnAddSession);
            conf_playback_callback_.OnPlaybackCompleteDelegate_ = new OnPlaybackCompleteDelegate(OnPlaybackComplete);
            conf_playback_callback_.OnPlaybackContinueDelegate_ = new OnPlaybackContinueDelegate(OnPlaybackContinue);
            conf_playback_callback_.OnPlaybackOpenDelegate_ = new OnPlaybackOpenDelegate(OnPlaybackOpen);
            conf_playback_callback_.OnPlaybackPauseDelegate_ = new OnPlaybackPauseDelegate(OnPlaybackPause);
            conf_playback_callback_.OnPlaybackPlayDelegate_ = new OnPlaybackPlayDelegate(OnPlaybackPlay);
            conf_playback_callback_.OnRemoveSessionDelegate_ = new OnRemoveSessionDelegate(OnRemoveSession);
            conf_playback_callback_.OnSessionVideoResolutionChangedDelegate_ = new OnSessionVideoResolutionChangedDelegate(OnSessionVideoResolutionChanged);
            lm_conf_playback_set_callback(c_instance_, ref conf_playback_callback_);
        }


        #region IConferencePlayback 成员

        public int AddObserver(IConferencePlaybackObserver observer)
        {
            if (observer_list_.Contains(observer))
                return -1;
            observer_list_.Add(observer);
            return 0;
        }

        public int RemoveObserver(IConferencePlaybackObserver observer)
        {
            observer_list_.Remove(observer);
            return 0;
        }

        public int StartPlayback(string file_name)
        {
            return lm_conf_playback_StartPlayback(c_instance_, file_name);
        }

        public int PlayPlayback(String[] play_accounts)
        {
            return lm_conf_playback_PlayPlayback(c_instance_, ref play_accounts[0], play_accounts.Length);
        }

        public int PausePlayback()
        {
            return lm_conf_playback_PausePlayback(c_instance_);
        }

        public int ContinuePlayback()
        {
            return lm_conf_playback_ContinuePlayback(c_instance_);
        }

        public int StopPlayback()
        {
            return lm_conf_playback_StopPlayback(c_instance_);
        }

        public int StartRepair(String file_name)
        {
            return lm_conf_playback_StartRepair(c_instance_, file_name);
        }

        public int StopRepair()
        {
            return lm_conf_playback_StopRepair(c_instance_);
        }

        public int AddPreview(uint rec_session, IntPtr windows, 
            ref int id_preview, int z_order, float left, float top, float right, float bottom)
        {
            return lm_conf_playback_AddPreview(c_instance_, (int)rec_session, windows, ref id_preview,
                z_order, left, top, right, bottom);
        }

        public int RemovePreview(uint rec_session, int id_preview)
        {
            return lm_conf_playback_RemovePreview(c_instance_, (int)rec_session, id_preview);
        }

        public int GetRenderSnapshot(uint rec_session, int id_preview, string file_name)
        {
            return lm_conf_playback_GetRenderSnapshot(c_instance_, (int)rec_session, id_preview, file_name);
        }

        #endregion
    }
}
